/**
 * 打开数据库
 * @param {object} params 数据库的名字
 * @param {string} dbName 数据库的名字
 * @param {string} storeName 仓库名称
 * @param {number} version 数据库的版本
 * @return {object} 该函数会返回一个数据库实例
 */
export function getNowTime() {
    return (new Date().getFullYear() + '-' +
        (new Date().getMonth() + 1) + '-' +
        new Date().getDate() + ' ' +
        new Date().getHours() + ':' +
        new Date().getMinutes() + ':' +
        new Date().getSeconds())
}

// 增加创建时间
export function addCreateTime(data) {
    return {...data, createTime: getNowTime()}
}

// 增加更新时间
export function addUpdateTime(data) {
    return {...data, updateTime: getNowTime()}
}


export function openDB(params, dbName = 'study', version = 1) {
    return new Promise((resolve, reject) => {
        //  兼容浏览器
        const indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
        let db;
        // 打开数据库，若没有则会创建
        const request = indexedDB.open(dbName, version);
        // 数据库打开成功回调
        request.onsuccess = function (event) {
            db = event.target.result; // 数据库对象
            // console.log("数据库打开成功");
            resolve(db);
        };
        // 数据库打开失败的回调
        request.onerror = function (event) {
            reject(event)
            // console.log("数据库打开报错");
        };
        // 数据库有更新时候的回调
        request.onupgradeneeded = function (event) {
            // 数据库创建或升级的时候会触发
            console.log("onupgradeneeded");
            db = event.target.result; // 数据库对象
            let objectStore;
            // 创建存储库
            objectStore = db.createObjectStore(params.objectStore, {
                keyPath: "id", // 这是主键
                // autoIncrement: true // 实现自增
            });
            let total = params.tableIndex
            total.forEach(v => {
                // 创建索引，在后面查询数据的时候可以根据索引查
                objectStore.createIndex(v, v, {unique: false});
            })
        };
    });
}

/**
 * 新增数据
 * @param {object} db 数据库实例
 * @param {string} storeName 仓库名称
 * @param {string} data 数据
 */
export function addData(storeName, data) {
    return new Promise((resolve, reject) => {
        openDB().then((db) => {
            const request = db
                .transaction([storeName], "readwrite") // 事务对象 指定表格名称和操作模式（"只读"或"读写"）
                .objectStore(storeName) // 仓库对象
                .add(data);

            request.onsuccess = function (event) {
                resolve(event)
                db.close()
                console.log("数据写入成功", event);
            };

            request.onerror = function (event) {
                reject(event)
                db.close()
                console.log("数据写入失败", event);
            };
        })

    })

}

/**
 * 通过索引和游标查询记录
 * @param {object} db 数据库实例
 * @param {string} storeName 仓库名称
 * @param {string} indexName 索引名称
 * @param {string} indexValue 索引值
 */
export function cursorGetDataByIndex(db, storeName, indexName, indexValue) {
    return new Promise((resolve, reject) => {
        let list = [];
        var store = db.transaction(storeName, "readwrite").objectStore(storeName); // 仓库对象
        var request = store
            .index(indexName) // 索引对象
            .openCursor(IDBKeyRange.only(indexValue)); // 指针对象
        request.onsuccess = function (e) {
            var cursor = e.target.result;
            if (cursor) {
                // 必须要检查
                list.push(cursor.value);
                cursor.continue(); // 遍历了存储对象中的所有内容
            } else {
                resolve(list)
                console.log("游标索引查询结果：", list);
            }
        };
        request.onerror = function (e) {
            reject(e)
            console.log("游标索引查询失败", e);
        };
    })

}

/**
 * 通过索引和游标分页查询记录
 * @param {object} db 数据库实例
 * @param {string} storeName 仓库名称
 * @param {string} indexName 索引名称
 * @param {number} indexValue 索引值
 * @param {number} page 页码
 * @param {number} pageSize 查询条数
 */
export function cursorGetDataByIndexAndPage(
    db,
    storeName,
    indexName,
    indexValue,
    page,
    pageSize
) {
    return new Promise((resolve, reject) => {
        let list = [];
        let counter = 0; // 计数器
        let advanced = true; // 是否跳过多少条查询
        var store = db.transaction(storeName, "readwrite").objectStore(storeName); // 仓库对象
        var request = store
            .index(indexName) // 索引对象
            .openCursor(IDBKeyRange.upperBound(indexValue)); // 指针对象
        request.onsuccess = function (e) {
            var cursor = e.target.result;
            if (page > 1 && advanced) {
                advanced = false;
                cursor.advance((page - 1) * pageSize); // 跳过多少条
                return;
            }
            if (cursor) {
                // 必须要检查
                list.push(cursor.value);
                counter++;
                if (counter < pageSize) {
                    cursor.continue(); // 遍历了存储对象中的所有内容
                } else {
                    cursor = null;
                    resolve(list)
                    console.log("分页查询结果", list);
                }
            } else {
                resolve(list)
                console.log("分页查询结果", list);
            }
        };
        request.onerror = function (e) {
            reject(e)
            console.log("分页查询失败");
        };
    })

}

/**
 * 更新数据
 * @param {object} db 数据库实例
 * @param {string} storeName 仓库名称
 * @param {object} data 数据
 */
export function updateDB(db, storeName, data) {
    return new Promise((resolve, reject) => {
        const request = db
            .transaction([storeName], "readwrite") // 事务对象
            .objectStore(storeName) // 仓库对象
            .put(data);

        request.onsuccess = function (res) {
            resolve(res)
            console.log('更新数据成功')
        };

        request.onerror = function (e) {
            reject(e)
            console.log('更新数据失败')
        };
    })

}


/**
 * 通过主键删除数据
 * @param {object} db 数据库实例
 * @param {string} storeName 仓库名称
 * @param {object} id 主键值
 */
export function deleteDB(db, storeName, id) {
    return new Promise((resolve, reject) => {
        var request = db
            .transaction([storeName], "readwrite")
            .objectStore(storeName)
            .delete(id);

        request.onsuccess = function (res) {
            resolve(res)
            console.log('数据删除成功')
        };

        request.onerror = function (e) {
            reject(e)
            console.log('数据删除失败')
        };
    })

}

/**
 * 通过索引和游标删除指定的数据
 * @param {object} db 数据库实例
 * @param {string} storeName 仓库名称
 * @param {string} indexName 索引名
 * @param {object} indexValue 索引值
 */
export function cursorDelete(db, storeName, indexName, indexValue) {
    return new Promise((resolve, reject) => {
        const store = db.transaction(storeName, "readwrite").objectStore(storeName);
        const request = store
            .index(indexName) // 索引对象
            .openCursor(IDBKeyRange.only(indexValue)); // 指针对象
        request.onsuccess = function (e) {
            const cursor = e.target.result;
            let deleteRequest;
            if (cursor) {
                deleteRequest = cursor.delete(); // 请求删除当前项
                deleteRequest.onerror = function (e) {
                    reject(e)
                    console.log('数据删除失败')
                };
                deleteRequest.onsuccess = function (res) {
                    resolve(res)
                    console.log('数据删除成功')
                };
                cursor.continue();
            }
        };
        request.onerror = function (e) {
            reject(e)
            console.log('数据删除失败')
        };
    })

}

/**
 * 关闭数据库
 * @param {object} db 数据库实例
 */
export function closeDB(db) {
    db.close();
    console.log("数据库已关闭");
}

